const fs = require('fs')
const path = require('path')
export const persistentCachePlugin = () => {
  let _server: any
  let cache = {}
  const cachePath = path.resolve('./', 'node_modules/.vite/cache/')
  return {
    name: 'persistent-cache-plugin',
    configureServer: async server => {
      _server = server
      server.middlewares.use((req, res, next) => {
        if (cache[req.url]) {
          const ifNoneMatch = req.headers['if-none-match']
          if (ifNoneMatch && cache[req.url] === ifNoneMatch) {
            const { moduleGraph, transformRequest } = server
            if (
              moduleGraph.urlToModuleMap.size &&
              moduleGraph.urlToModuleMap.get(req.url) &&
              moduleGraph.urlToModuleMap.get(req.url).transformResult
            ) {
              next()
              return
            } else {
              res.statusCode = 304
              setTimeout(() => {
                transformRequest(req.url, server, {
                  html: req.headers.accept?.includes('text/html')
                })
              }, 3000)
              return res.end()
            }
          }
        }
        next()
      })
    },
    buildStart: async () => {
      if (fs.existsSync(cachePath + '/cache.json')) {
        cache = require(cachePath + '/cache.json')
      }
      process.once('SIGINT', async () => {
        try {
          await _server.close()
        } finally {
          process.exit()
        }
      })
    },
    buildEnd: async () => {
      if (!fs.existsSync(cachePath)) {
        fs.mkdirSync(cachePath)
      }
      for (const [key, value] of _server.moduleGraph.urlToModuleMap) {
        if (value.transformResult && value.transformResult.etag) {
          cache[key] = value.transformResult.etag
        }
      }
      fs.writeFileSync(cachePath + '/cache.json', JSON.stringify(cache), err => {
        console.log(err)
      })
    }
  }
}
